---@class components
---@field webbert_transplant component_webbert_transplant

-- local function on_val(self, value)
    -- self.inst.replica.webbert_transplant:SetVal(value)
-- end

---@class component_webbert_transplant
---@field inst ent
local webbert_transplant = Class(

---@param self component_webbert_transplant
---@param inst ent
function(self, inst)
    self.inst = inst
    -- self.val = 0
end,
nil,
{
    -- val = on_val,
})

-- function webbert_transplant:OnSave()
--     return {
--         -- val = self.val
--     }
-- end

-- function webbert_transplant:OnLoad(data)
--     -- self.val = data.val or 0
-- end

---comment
---@param x number
---@param y number
---@param z number
---@param cx number
---@param cy number
---@param cz number
---@param spacing number
---@param pointnums integer
---@return {[1]:number, [2]:number}[]
---@nodiscard
local function calcPoints(x,y,z,cx,cy,cz,spacing,pointnums)
    local points = {}
    for i = 0,(pointnums-1) do
        for j = 0,(pointnums-1) do
            local px = cx + spacing * (i-1.5) / pointnums
            local pz = cz + spacing * (j-1.5) / pointnums
            table.insert(points,{px,pz})
        end
    end
    return points
end

---comment
---@param doer ent
---@param target ent
---@return boolean
function webbert_transplant:DoAction(doer,target)
    local neednum = 16 -- 移植最大数量
    local plant_prefab = 'sapling' -- 种植后的产物prefabID
    local all_plant = {
        sapling = true,
        grass = true,
    }

    local target_prefab = target.prefab
    if target_prefab == 'dug_sapling' then
        neednum = 16
        plant_prefab = 'sapling'
    elseif target_prefab == 'dug_grass' then
        neednum = 16
        plant_prefab = 'grass'
    end
    -- 目标坐标
    local x,y,z = target:GetPosition():Get()
    if not SUGAR_webber_the_trainer:checkPositionIsGround(x,0,z) then
        return true
    end

    -- 目标的地皮中心点
    local cx,cy,cz = TheWorld.Map:GetTileCenterPoint(x,y,z)
    -- 以地皮中心点为圆心，扫描范围内同prefabID实体
    local ents = TheSim:FindEntities(cx,cy,cz, 3,nil,{"INLIMBO"})

    -- 扫到的目标的一部分都在这个里面
    ---@type ent[]
    local targets = {}
    local count = 0
    for k,v in pairs(ents) do
        -- 如果该地皮找到了植物,则判定为该地皮已被种植过,则直接返回
        if all_plant[v.prefab] then
            local tar_cx,_,tar_cz = TheWorld.Map:GetTileCenterPoint(v:GetPosition():Get())
            if tar_cx == cx and tar_cz == cz then
                if doer.components.talker then
                    doer.components.talker:Say(STRINGS.MOD_WEBBER_THE_TRAINER.ACTIONS.ACTION_WEBBERT_STAFF_TRANSPLANT_failed_for_already_transplanted)
                end
                return true
            end
        end
        if v.prefab == target_prefab then
            if v.components.stackable then
                count = count + v.components.stackable:StackSize()
            else
                count = count + 1
            end
            table.insert(targets,v)
        end
        if count >= neednum then
            break
        end
    end
    -- 数量不够
    if count < neednum then
        if doer.components.talker then
            doer.components.talker:Say(STRINGS.MOD_WEBBER_THE_TRAINER.ACTIONS.ACTION_WEBBERT_STAFF_TRANSPLANT_failed_for_notenough)
        end
        return true
    end


    if target_prefab == 'dug_sapling' then
        local points = calcPoints(x,y,z,cx,cy,cz,3.8,4)
        for i,v in ipairs(points) do
            TheWorld:DoTaskInTime(i/5,function ()
                local plant = SpawnPrefab('sapling')
                plant.Transform:SetPosition(v[1],0,v[2])
                plant.components.pickable:MakeEmpty()
                plant.AnimState:PlayAnimation('dead_to_empty')
                plant.AnimState:PushAnimation('empty',false)
            end)
        end
    elseif target_prefab == 'dug_grass' then
        local points = calcPoints(x,y,z,cx,cy,cz,3.8,4)
        for i,v in ipairs(points) do
            TheWorld:DoTaskInTime(i/5,function ()
                local plant = SpawnPrefab('grass')
                plant.Transform:SetPosition(v[1],0,v[2])
                plant.components.pickable:OnTransplant()
            end)
        end
    end

    -- 扣除素材 
    count = 0
    for k,v in pairs(targets) do
        for i = 1, (v.components.stackable and v.components.stackable:StackSize() or 1) do
            count = count + (SUGAR_webber_the_trainer:consumeOneItem(v) and 1 or 0)

            if count >= neednum then
                break
            end
        end
    end

    ---@diagnostic disable-next-line: cast-local-type
    targets = nil

    return true
end

return webbert_transplant